package org.kolonitsky.translator;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kolonitsky.translator.utils.TextUtils;

import java.io.UnsupportedEncodingException;
import java.net.*;

import static org.kolonitsky.translator.Settings.ENCODING;

/**
 * @author Alex.Kolonitsky
 */

public abstract class ServiceTranslator extends BaseTranslator {
    protected static final Log LOG = LogFactory.getLog(Translator.class);

    protected static final int DEFAULT_LIMIT = 400;

    private final int limit;

    private int exceptionCount = 0;

    public ServiceTranslator(Lang to) {
    	this(to, DEFAULT_LIMIT);
    }

    public ServiceTranslator(Lang from, Lang to) {
        this(from, to, DEFAULT_LIMIT);
    }

    public ServiceTranslator(Lang to, int limit) {
        super(to);
        this.limit = limit;
    }

    public ServiceTranslator(Lang from, Lang to, int limit) {
        super(from, to);
        this.limit = limit;
    }

    protected abstract URL getUrl(String text) throws MalformedURLException, UnsupportedEncodingException;

    protected abstract String translateChunk(String text);
    
    public String send(String text) {
        try {
            URL url = getUrl(text);
            final HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            uc.setRequestMethod("GET");
            uc.setRequestProperty("Accept-Charset", ENCODING);

            try {
                return IOUtils.toString(uc.getInputStream(), ENCODING);
            } finally { // http://java.sun.com/j2se/1.5.0/docs/guide/net/http-keepalive.html
                uc.getInputStream().close();
                if (uc.getErrorStream() != null) {
                    uc.getErrorStream().close();
                }
            }
        } catch (Exception e) {
            exceptionCount++;
            LOG.warn(getClass().getSimpleName() + " translation failed for: '" + text + "'", e);
        }

        return null;
    }

    public String translate(String text) {
        if(exceptionCount <3){
            StringBuilder res = new StringBuilder();
            for (String chunk : TextUtils.chunkText(text, limit)) {
                String translate = decode(translateChunk(chunk));
                if (translate != null) {
                    res.append(translate);
                }
            }

            if (res.length() == 0) {
                return null;
            }

            return res.toString();
        }
        return null;
    }

    private String decode(String string) {
        return string.replace("&lt;", "<")
                     .replace("&gt;", ">")
                     .replace("&amp;", "&");
    }
}
